home *** CD-ROM | disk | FTP | other *** search
- /*
- *=============================================================================
- * tSippPoly.c
- *-----------------------------------------------------------------------------
- * Tcl commands to manage SIPP polygons and surfaces.
- *-----------------------------------------------------------------------------
- * Copyright 1992 Mark Diekhans
- * Permission to use, copy, modify, and distribute this software and its
- * documentation for any purpose and without fee is hereby granted, provided
- * that the above copyright notice appear in all copies. Mark Diekhans makes
- * no representations about the suitability of this software for any purpose.
- * It is provided "as is" without express or implied warranty.
- *-----------------------------------------------------------------------------
- * $Id: tSippPoly.c,v 2.0 1992/11/02 03:56:30 markd Rel $
- *=============================================================================
- */
-
- #include "tSippInt.h"
- #include "primitives.h"
-
- /*
- * Internal prototypes.
- */
- static void
- BindSurfaceToHandle _ANSI_ARGS_((tSippGlob_pt tSippGlobPtr,
- Surface *surfacePtr));
-
- static bool
- PushVertexList _ANSI_ARGS_((tSippGlob_pt tSippGlobPtr,
- bool textures,
- char *vertexList));
-
- static bool
- PushVertexArgList _ANSI_ARGS_((tSippGlob_pt tSippGlobPtr,
- int argc,
- char **argv));
- /*=============================================================================
- * BindSurfaceToHandle --
- * Assigns a handle to the specified surface.
- * Parameters:
- * o tSippGlobPtr (I) - Pointer to the Tcl SIPP globals. The handle is
- * returned in interp->result.
- * o surfacePtr (I) - A pointer to the surface.
- *-----------------------------------------------------------------------------
- */
- static void
- BindSurfaceToHandle (tSippGlobPtr, surfacePtr)
- tSippGlob_pt tSippGlobPtr;
- Surface *surfacePtr;
- {
- Surface **surfaceEntryPtr;
-
- surfaceEntryPtr = (Surface **)
- Tcl_HandleAlloc (tSippGlobPtr->surfaceTblPtr,
- tSippGlobPtr->interp->result);
- *surfaceEntryPtr = surfacePtr;
- surfacePtr->ref_count++;
-
- } /* BindSurfaceToHandle */
-
- /*=============================================================================
- * TSippSurfaceHandleToPtr --
- * Utility procedure to convert a surface handle to a surface pointer.
- * For use of by functions outside of this module.
- * Parameters:
- * o tSippGlobPtr (I) - A pointer to the Tcl SIPP global structure.
- * o handle (I) - A surface handle.
- * Returns:
- * A pointer to the surface, or NULL if an error occured.
- *-----------------------------------------------------------------------------
- */
- Surface *
- TSippSurfaceHandleToPtr (tSippGlobPtr, handle)
- tSippGlob_pt tSippGlobPtr;
- char *handle;
- {
- Surface **surfaceEntryPtr;
-
- surfaceEntryPtr = (Surface **)
- Tcl_HandleXlate (tSippGlobPtr->interp,
- tSippGlobPtr->surfaceTblPtr, handle);
- if (surfaceEntryPtr == NULL)
- return NULL;
- return *surfaceEntryPtr;
-
- } /* TSippSurfaceHandleToPtr */
-
- /*=============================================================================
- * PushVertexList --
- * Parse, convert a list of vertex coordinates, and optional texture
- * coordinates on the vertex stack.
- * Parameters:
- * o tSippGlobPtr (I) - A pointer to the Tcl SIPP global structure.
- * o textures (I) - TRUE if texture coordinates are includes, FALSE if not.
- * o vertexList (I) - A list of lists of vertex coordinates or vertex and
- * texture coordinates pairs.
- * Returns:
- * TRUE if the list and numbers are valid, FALSE if there is an error.
- *-----------------------------------------------------------------------------
- */
- static bool
- PushVertexList (tSippGlobPtr, textures, vertexList)
- tSippGlob_pt tSippGlobPtr;
- bool textures;
- char *vertexList;
- {
- int vertexArgc, idx;
- char **vertexArgv;
- Vector vertex, textureCoord;
-
- if (Tcl_SplitList (tSippGlobPtr->interp, vertexList, &vertexArgc,
- &vertexArgv) != TCL_OK)
- return FALSE;
- if (textures) {
- for (idx = 0; idx < vertexArgc; idx ++) {
- if (!TSippConvertVertexTex (tSippGlobPtr, vertexArgv [idx],
- &vertex, &textureCoord))
- goto errorExit;
- vertex_tx_push (vertex.x, vertex.y, vertex.z,
- textureCoord.x, textureCoord.y, textureCoord.z);
- }
- } else {
- for (idx = 0; idx < vertexArgc; idx ++) {
- if (!TSippConvertVertex (tSippGlobPtr, vertexArgv [idx], &vertex))
- goto errorExit;
- vertex_push (vertex.x, vertex.y, vertex.z);
- }
- }
-
- ckfree (vertexArgv);
- return TRUE;
- errorExit:
- ckfree (vertexArgv);
- return FALSE;
-
- } /* PushVertexList */
-
- /*=============================================================================
- * PushVertexArgList --
- * Handles parsing and processing arguments in the form:
- * [-tex] [vertexList]
- * Parameters:
- * o tSippGlobPtr (I) - A pointer to the Tcl SIPP global structure.
- * o argc, argv (I) - Command arguments.
- * Returns:
- * TRUE if all is ok, FALSE if there is an error.
- *-----------------------------------------------------------------------------
- */
- static bool
- PushVertexArgList (tSippGlobPtr, argc, argv)
- tSippGlob_pt tSippGlobPtr;
- int argc;
- char **argv;
- {
- bool textures;
- char *listPtr;
-
- if (argc == 3) {
- if (!STREQU (argv [1], "-tex")) {
- Tcl_AppendResult (tSippGlobPtr->interp,
- "expected option of `-tex', got `",
- argv [1], "'", (char *) NULL);
- return FALSE;
- }
- textures = TRUE;
- listPtr = argv [2];
- } else {
- textures = FALSE;
- listPtr = argv [1];
- }
- return PushVertexList (tSippGlobPtr, textures, listPtr);
-
- } /* PushVertexArgList */
-
- /*=============================================================================
- * SippVertexPush --
- * Implements the command:
- * SippVertexPush [-tex] vertexList
- * Note:
- * This procedure has standard Tcl command calling sematics. ClientData
- * contains a pointer to the Tcl SIPP global structure.
- *-----------------------------------------------------------------------------
- */
- static int
- SippVertexPush (clientData, interp, argc, argv)
- char *clientData;
- Tcl_Interp *interp;
- int argc;
- char **argv;
- {
- if ((argc < 2) || (argc > 3)) {
- Tcl_AppendResult (interp, "wrong # args: ", argv [0],
- " [-tex] vertexList", (char *) NULL);
- return TCL_ERROR;
- }
- if (PushVertexArgList ((tSippGlob_pt) clientData, argc, argv))
- return TCL_OK;
- else
- return TCL_ERROR;
-
- } /* SippVertexPush */
-
- /*=============================================================================
- * SippPolygonPush --
- * Implements the command:
- * SippPolygonPush [[-tex] vertexList]
- * Note:
- * This procedure has standard Tcl command calling sematics. ClientData
- * contains a pointer to the Tcl SIPP global structure.
- *-----------------------------------------------------------------------------
- */
- static int
- SippPolygonPush (clientData, interp, argc, argv)
- char *clientData;
- Tcl_Interp *interp;
- int argc;
- char **argv;
- {
- bool textures;
-
- if (argc > 3) {
- Tcl_AppendResult (interp, "wrong # args: ", argv [0],
- " [[-tex] vertexList]", (char *) NULL);
- return TCL_ERROR;
- }
- if (argc > 1) {
- if (!PushVertexArgList ((tSippGlob_pt) clientData, argc, argv))
- return TCL_ERROR;
- }
-
- polygon_push ();
- return TCL_OK;
-
- } /* SippPolygonPush */
-
- /*=============================================================================
- * SippSurfaceCreate --
- * Implements the command:
- * SippSurfaceCreate shaderhandle
- * Note:
- * This procedure has standard Tcl command calling sematics. ClientData
- * contains a pointer to the Tcl SIPP global structure.
- *-----------------------------------------------------------------------------
- */
- static int
- SippSurfaceCreate (clientData, interp, argc, argv)
- char *clientData;
- Tcl_Interp *interp;
- int argc;
- char **argv;
- {
- tSippGlob_pt tSippGlobPtr = (tSippGlob_pt) clientData;
- Surface *surfacePtr;
- Shader *shaderPtr;
- void *surfDescPtr;
-
- if (argc != 2) {
- Tcl_AppendResult (interp, "wrong # args: ", argv [0], " shaderhandle",
- (char *) NULL);
- return TCL_ERROR;
- }
-
- shaderPtr = TSippShaderHandleToPtr (tSippGlobPtr, argv [1],
- &surfDescPtr);
- if (shaderPtr == NULL)
- return TCL_ERROR;
-
- surfacePtr = surface_create (surfDescPtr, shaderPtr);
- if (surfacePtr == NULL) {
- Tcl_AppendResult (interp, "the polygon stack is empty",
- (char *) NULL);
- return TCL_ERROR;
- }
-
- BindSurfaceToHandle (tSippGlobPtr, surfacePtr);
- return TCL_OK;
-
- } /* SippSurfaceCreate */
-
- /*=============================================================================
- * SippSurfaceDelete --
- * Implements the command:
- * SippSurfaceDelete surfacelist
- * Note:
- * This procedure has standard Tcl command calling sematics. ClientData
- * contains a pointer to the Tcl SIPP global structure.
- *-----------------------------------------------------------------------------
- */
- static int
- SippSurfaceDelete (clientData, interp, argc, argv)
- char *clientData;
- Tcl_Interp *interp;
- int argc;
- char **argv;
- {
- tSippGlob_pt tSippGlobPtr = (tSippGlob_pt) clientData;
- int idx;
- handleList_t surfaceList;
- handleList_t surfaceEntryList;
-
- if (argc != 2) {
- Tcl_AppendResult (interp, "wrong # args: ", argv [0],
- " surfacelist", (char *) NULL);
- return TCL_ERROR;
- }
- if (!TSippHandleListConvert (tSippGlobPtr, tSippGlobPtr->surfaceTblPtr,
- argv [1], &surfaceList, &surfaceEntryList))
- return TCL_ERROR;
-
- for (idx = 0; idx < surfaceList.len; idx++) {
- Surface * surfacePtr = (surfaceList.ptr [idx]);
-
- surfacePtr->ref_count--;
- Tcl_HandleFree (tSippGlobPtr->surfaceTblPtr,
- surfaceEntryList.ptr [idx]);
- }
-
- TSippHandleListFree (&surfaceList);
- TSippHandleListFree (&surfaceEntryList);
- return TCL_OK;
-
- } /* SippSurfaceDelete */
-
- /*=============================================================================
- * SippSurfaceSetShader --
- * Implements the command:
- * SippSurfaceSetShader surfacelist shaderhandle
- * Note:
- * This procedure has standard Tcl command calling sematics. ClientData
- * contains a pointer to the Tcl SIPP global structure.
- *-----------------------------------------------------------------------------
- */
- static int
- SippSurfaceSetShader (clientData, interp, argc, argv)
- char *clientData;
- Tcl_Interp *interp;
- int argc;
- char **argv;
- {
- tSippGlob_pt tSippGlobPtr = (tSippGlob_pt) clientData;
- int idx;
- handleList_t surfaceList;
- Shader *shaderPtr;
- void *surfDescPtr;
-
- if (argc != 3) {
- Tcl_AppendResult (interp, "wrong # args: ", argv [0],
- " surfacelist shaderhandle", (char *) NULL);
- return TCL_ERROR;
- }
-
- if (!TSippHandleListConvert (tSippGlobPtr, tSippGlobPtr->surfaceTblPtr,
- argv [1], &surfaceList, NULL))
- return TCL_ERROR;
-
- shaderPtr = TSippShaderHandleToPtr (tSippGlobPtr, argv [2], &surfDescPtr);
- if (shaderPtr == NULL)
- goto errorExit;
-
- for (idx = 0; idx < surfaceList.len; idx++)
- surface_set_shader ((Surface *) surfaceList.ptr [idx], surfDescPtr,
- shaderPtr);
-
- TSippHandleListFree (&surfaceList);
- return TCL_OK;
- errorExit:
- TSippHandleListFree (&surfaceList);
- return TCL_ERROR;
-
- } /* SippSurfaceSetShader */
-
- /*=============================================================================
- * TSippPolyInit --
- * Initialized the polygon and surface commands, including creating the
- * polygon table.
- *
- * Parameters:
- * o tSippGlobPtr (I) - A pointer to the Tcl SIPP global structure.
- *-----------------------------------------------------------------------------
- */
- void
- TSippPolyInit (tSippGlobPtr)
- tSippGlob_pt tSippGlobPtr;
- {
- static tSippTclCmdTbl_t cmdTable [] = {
- {"SippVertexPush", SippVertexPush},
- {"SippPolygonPush", SippPolygonPush},
- {"SippSurfaceCreate", SippSurfaceCreate},
- {"SippSurfaceDelete", SippSurfaceDelete},
- {"SippSurfaceSetShader", SippSurfaceSetShader},
- {NULL, NULL}
- };
-
- tSippGlobPtr->surfaceTblPtr =
- Tcl_HandleTblInit ("surface", sizeof (Surface *), 24);
-
- TSippInitCmds (tSippGlobPtr, cmdTable);
-
- } /* TSippPolyInit */
-
-